home *** CD-ROM | disk | FTP | other *** search
- // UIElements.cpp : implementation file
- //
-
- #include "stdafx.h"
- #include "effectedit.h"
- #include "UIElements.h"
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CUIElements
-
- CUIElements::CUIElements()
- {
- m_pMeshArrow = NULL;
- m_pEffect = NULL;
- m_pd3dFont = NULL;
- m_fObjectRadius = 1.0f;
- }
-
- CUIElements::~CUIElements()
- {
- DeleteAllElements();
- }
-
- HRESULT CUIElements::OnCreateDevice( LPDIRECT3DDEVICE9 pd3dDevice )
- {
- if( m_pd3dFont == NULL )
- D3DXCreateFont( pd3dDevice, -12, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
- OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
- _T("Arial"), &m_pd3dFont );
-
- D3DXLoadMeshFromXResource( NULL, (LPCSTR)MAKEINTRESOURCE(IDR_ARROW_X), "X", D3DXMESH_MANAGED,
- pd3dDevice, NULL, NULL, NULL, NULL, &m_pMeshArrow );
- D3DXCreateEffectFromResource( pd3dDevice, NULL, MAKEINTRESOURCE(IDR_UIELEMENT_FX),
- NULL, NULL, 0, NULL, &m_pEffect, NULL );
-
- return S_OK;
- }
-
- HRESULT CUIElements::OnResetDevice( LPDIRECT3DDEVICE9 pd3dDevice )
- {
- if( m_pEffect != NULL )
- m_pEffect->OnResetDevice();
- m_pd3dFont->OnResetDevice();
- return S_OK;
- }
-
- void CUIElements::OnLostDevice()
- {
- if( m_pEffect != NULL )
- m_pEffect->OnLostDevice();
- m_pd3dFont->OnLostDevice();
- }
-
- void CUIElements::OnDestroyDevice()
- {
- DeleteEffectObjects();
- SAFE_RELEASE( m_pMeshArrow );
- SAFE_RELEASE( m_pEffect );
- SAFE_RELEASE( m_pd3dFont );
- }
-
- void CUIElements::SetInfo( UINT bbWidth, UINT bbHeight, D3DXMATRIX* pMatProj )
- {
- m_bbWidth = bbWidth;
- m_bbHeight = bbHeight;
- m_matProj = *pMatProj;
- }
-
- void CUIElements::SetMatView( D3DXMATRIX* pMatView )
- {
- m_matView = *pMatView;
- }
-
- HRESULT CUIElements::RenderArrow( BOOL bSelected )
- {
- UINT numPasses;
- if( bSelected )
- m_pEffect->SetTechnique( m_pEffect->GetTechniqueByName("Selected") );
- else
- m_pEffect->SetTechnique( m_pEffect->GetTechniqueByName("Unselected") );
- m_pEffect->Begin( &numPasses, 0 );
- for( UINT iPass = 0; iPass < numPasses; iPass++ )
- {
- m_pEffect->BeginPass( iPass );
- m_pMeshArrow->DrawSubset( 0 );
- m_pMeshArrow->DrawSubset( 1 );
- m_pEffect->EndPass();
- }
- m_pEffect->End();
-
- return S_OK;
- }
-
- HRESULT CUIElements::Render( IDirect3DDevice9 *pd3dDevice )
- {
- CUIElement* pUIElement;
-
- for( POSITION pos = m_UIElementList.GetHeadPosition(); pos != NULL; )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetNext( pos );
- pUIElement->Render( pd3dDevice );
- }
- return S_OK;
- }
-
- // Go through pEffect and hook up existing UI objects to parameters,
- // and create new UI objects for other parameters
- void CUIElements::InitEffectObjects( LPD3DXEFFECT pEffect )
- {
- D3DXEFFECT_DESC EffectDesc;
- D3DXPARAMETER_DESC ParamDesc;
- D3DXHANDLE hParam;
- D3DXHANDLE hAnnot;
- CUIElement* pElement;
- LPCSTR pstrName;
- CString strParamName;
- CString strAnnotName;
-
- pEffect->GetDesc( &EffectDesc );
- for( UINT iParam = 0; iParam < EffectDesc.Parameters; iParam++ )
- {
- hParam = pEffect->GetParameter ( NULL, iParam );
-
- // See if param has a UIDirectional annotation
- hAnnot = pEffect->GetAnnotationByName( hParam, "UIDirectional" );
- if( hAnnot != NULL )
- {
- pEffect->GetParameterDesc( hParam, &ParamDesc );
- strParamName = ParamDesc.Name;
-
- // See if we already have a UIElement with with that name
- pEffect->GetString( hAnnot, &pstrName);
- strAnnotName = pstrName;
- if( FindElement( strAnnotName, &pElement ) )
- {
- // Element exists, so hook it up to this hParam
- pElement->SetParamName( strParamName );
- pElement->SetParam( pEffect, hParam, FALSE );
- }
- else
- {
- // Element doesn't exist, so create one based on the type
- CDirLight* pDirLight;
- pDirLight = new CDirLight(this);
- if( pDirLight == NULL )
- return;
- pDirLight->SetAnnotName( strAnnotName );
- pDirLight->SetParamName( strParamName );
- pDirLight->SetParam( pEffect, hParam, TRUE );
- m_UIElementList.AddHead( pDirLight );
- }
- }
- }
-
- // Destroy any UIElements that aren't attached to a handle by now
- CUIElement* pUIElement;
-
- POSITION pos1, pos2;
- for( pos1 = m_UIElementList.GetHeadPosition(); (pos2 = pos1) != NULL; )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetNext( pos1 );
- if( pUIElement->GetParamHandle() == NULL )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetAt(pos2);
- m_UIElementList.RemoveAt(pos2);
- delete pUIElement;
- }
- }
- }
-
- // Drop all effect-specific objects (parameter handles)
- void CUIElements::DeleteEffectObjects()
- {
- CUIElement* pUIElement;
-
- for( POSITION pos = m_UIElementList.GetHeadPosition(); pos != NULL; )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetNext( pos );
- pUIElement->SetParam(NULL, NULL, FALSE);
- }
- }
-
- BOOL CUIElements::FindElement( CString& strAnnotName, CUIElement** ppElement )
- {
- *ppElement = NULL;
-
- CUIElement* pUIElement;
-
- for( POSITION pos = m_UIElementList.GetHeadPosition(); pos != NULL; )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetNext( pos );
- if( pUIElement->GetAnnotName() == strAnnotName )
- {
- *ppElement = pUIElement;
- return TRUE;
- }
- }
- return FALSE;
- }
-
-
- void CUIElements::SetEffectParameters( LPD3DXEFFECT pEffect )
- {
- CUIElement* pUIElement;
-
- for( POSITION pos = m_UIElementList.GetHeadPosition(); pos != NULL; )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetNext( pos );
- pUIElement->SetEffectParameters( pEffect );
- }
- }
-
- void CUIElements::HandleMouseDown( INT x, INT y, BOOL* pbSetCapture )
- {
- *pbSetCapture = FALSE;
-
- CUIElement* pUIElement;
-
- for( POSITION pos = m_UIElementList.GetHeadPosition(); pos != NULL; )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetNext( pos );
- pUIElement->HandleMouseDown( x, y, pbSetCapture );
- if( *pbSetCapture )
- return;
- }
- }
-
- void CUIElements::HandleMouseMove( INT x, INT y )
- {
- CUIElement* pUIElement;
-
- for( POSITION pos = m_UIElementList.GetHeadPosition(); pos != NULL; )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetNext( pos );
- pUIElement->HandleMouseMove( x, y );
- }
- }
-
- void CUIElements::HandleMouseUp()
- {
- CUIElement* pUIElement;
-
- for( POSITION pos = m_UIElementList.GetHeadPosition(); pos != NULL; )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetNext( pos );
- pUIElement->HandleMouseUp();
- }
- }
-
-
- BOOL CUIElements::IsDragging()
- {
- CUIElement* pUIElement;
-
- for( POSITION pos = m_UIElementList.GetHeadPosition(); pos != NULL; )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetNext( pos );
- if( pUIElement->IsDragging() )
- return TRUE;
- }
- return FALSE;
- }
-
- void CUIElements::DeleteAllElements()
- {
- CUIElement* pUIElement;
-
- for( POSITION pos = m_UIElementList.GetHeadPosition(); pos != NULL; )
- {
- pUIElement = (CUIElement*)m_UIElementList.GetNext( pos );
- delete pUIElement;
- }
- m_UIElementList.RemoveAll();
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CDirLight
-
- CDirLight::CDirLight(CUIElements* pUIElements)
- {
- m_pUIElements = pUIElements;
- m_fTheta = D3DX_PI / 2;
- m_fRho = -D3DX_PI / 4;
- m_bDragging = FALSE;
- m_bSelected = FALSE;
- m_vec.x = 0.0f;
- m_vec.y = 0.0f;
- m_vec.z = 1.0f;
- }
-
- void CDirLight::Update()
- {
- FLOAT fScaleFactor = m_pUIElements->m_fObjectRadius * 0.25f;
- D3DXMATRIX matScale;
- D3DXMATRIX matTrans;
- D3DXMATRIX matRot;
- D3DXMatrixScaling( &matScale, fScaleFactor, fScaleFactor, fScaleFactor );
- D3DXMatrixTranslation( &matTrans, 0, 0, m_pUIElements->m_fObjectRadius * 0.75f );
- D3DXMatrixRotationYawPitchRoll( &matRot, m_fTheta, m_fRho, 0 );
- m_matWorld = matScale * matTrans * matRot;
-
- D3DXVECTOR3 vec(0, 0, 1);
- D3DXVec3TransformCoord( &m_vec, &vec, &m_matWorld );
- m_vec = -m_vec;
- D3DXVec3Normalize(&m_vec, &m_vec);
- }
-
- void CDirLight::SetEffectParameters( LPD3DXEFFECT pEffect )
- {
- Update();
- if( m_hParam != NULL )
- {
- D3DXVECTOR4 vec(m_vec.x, m_vec.y, m_vec.z, 1.0f);
- pEffect->SetVector( m_hParam, &vec );
- }
- }
-
- void CDirLight::Render( IDirect3DDevice9* pd3dDevice )
- {
- pd3dDevice->SetTransform( D3DTS_WORLD, &m_matWorld );
- m_pUIElements->RenderArrow(m_bSelected);
- if( m_bSelected )
- {
- D3DXVECTOR3 vec;
- D3DXMATRIX mat;
- mat = m_matWorld * m_pUIElements->m_matView * m_pUIElements->m_matProj;
- vec.x = 0; vec.y = 0; vec.z = 0;
- D3DXVec3TransformCoord( &vec, &vec, &mat );
- vec.x = vec.x * m_pUIElements->m_bbWidth / 2 + m_pUIElements->m_bbWidth / 2;
- vec.y = -vec.y * m_pUIElements->m_bbHeight / 2 + m_pUIElements->m_bbHeight / 2;
- CString str;
- str.Format(TEXT("%s\n(%0.2f, %0.2f, %0.2f)"), m_strAnnotName, m_vec.x, m_vec.y, m_vec.z );
- RECT rc = { (LONG)vec.x + 1, (LONG)vec.y + 1, (LONG)vec.x + 1, (LONG)vec.y + 1 };
- m_pUIElements->m_pd3dFont->DrawText( NULL, str, -1, &rc, DT_LEFT|DT_NOCLIP, 0xff000000 );
- OffsetRect( &rc, -1, -1 );
- m_pUIElements->m_pd3dFont->DrawText( NULL, str, -1, &rc, DT_LEFT|DT_NOCLIP, 0xffffffff );
- }
- }
-
- void CDirLight::SetParam( LPD3DXEFFECT pEffect, D3DXHANDLE hParam, BOOL bPickUpDefault )
- {
- HRESULT hr;
- D3DXVECTOR4 vec;
- m_hParam = hParam;
-
- if( pEffect == NULL )
- return;
-
- if( bPickUpDefault )
- {
- hr = pEffect->GetVector( hParam, &vec );
-
- if( vec.x == 0 && vec.y == 0 && vec.z == 0 )
- {
- m_fTheta = D3DX_PI / 2;
- m_fRho = -D3DX_PI / 4;
- }
- else
- {
- vec = -vec;
- D3DXVec4Normalize( &vec, &vec );
- m_fTheta = atan2f(vec.x, vec.z);
- m_fRho = -vec.y * D3DX_PI / 2;
- }
- Update();
- }
- }
-
- void CDirLight::HandleMouseDown( INT x, INT y, BOOL* pbSetCapture )
- {
- *pbSetCapture = FALSE;
- if( MouseOverLight( x, y ) )
- {
- *pbSetCapture = TRUE;
- m_hCur = SetCursor(NULL);
- m_bDragging = TRUE;
- m_xDown = x;
- m_yDown = y;
- m_fThetaDown = m_fTheta;
- m_fRhoDown = m_fRho;
- }
- }
-
- void CDirLight::HandleMouseMove( INT x, INT y )
- {
- if( m_bDragging )
- {
- INT dx = m_xDown - x;
- INT dy = y - m_yDown;
-
- float fdx = dx / 100.0f;
- float fdy = dy / 100.0f;
-
- m_fTheta = m_fThetaDown + fdx;
- m_fRho = m_fRhoDown + fdy;
-
- if( m_fRho > D3DX_PI / 2 )
- m_fRho = D3DX_PI / 2;
- if( m_fRho < -D3DX_PI / 2 )
- m_fRho = -D3DX_PI / 2;
- Update();
- }
- else
- {
- if( MouseOverLight( x, y ) )
- {
- m_bSelected = TRUE;
- }
- else
- {
- m_bSelected = FALSE;
- }
- }
- }
-
- void CDirLight::HandleMouseUp()
- {
- if( m_bDragging )
- {
- m_bDragging = FALSE;
- ReleaseCapture();
- SetCursor(m_hCur);
- m_hCur = NULL;
- }
- }
-
- BOOL CDirLight::MouseOverLight(INT x, INT y)
- {
- D3DXVECTOR3 vecRayPos;
- D3DXVECTOR3 vecRayDir;
- BOOL bHit = FALSE;
-
- D3DXVECTOR3 vPickRayDir;
- D3DXVECTOR3 vPickRayOrig;
-
- // Get the pick ray from the mouse position
-
- // Compute the vector of the pick ray in screen space
- D3DXVECTOR3 v;
- v.x = ( ( ( 2.0f * x ) / m_pUIElements->m_bbWidth ) - 1 ) / m_pUIElements->m_matProj._11;
- v.y = -( ( ( 2.0f * y ) / m_pUIElements->m_bbHeight ) - 1 ) / m_pUIElements->m_matProj._22;
- v.z = 1.0f;
-
- // Get the inverse worldview matrix
- D3DXMATRIXA16 m1, m;
- m1 = m_matWorld * m_pUIElements->m_matView;
- D3DXMatrixInverse( &m, NULL, &m1 );
-
- // Transform the screen space pick ray into 3D space
- vPickRayDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31;
- vPickRayDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32;
- vPickRayDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33;
- vPickRayOrig.x = m._41;
- vPickRayOrig.y = m._42;
- vPickRayOrig.z = m._43;
-
- D3DXIntersect( m_pUIElements->m_pMeshArrow, &vPickRayOrig, &vPickRayDir, &bHit,
- NULL, NULL, NULL, NULL, NULL, NULL );
- return bHit;
- }
-
-